﻿#include <QUndoCommand>
#include <QGraphicsScene>
#include <QGraphicsItem>

namespace Y_Image_Drawer_GUI {
    class YGraphicsItem;
    class YGraphicsTipItemPanel;

    // 添加元素时undo/redo
    class AddCommand : public QUndoCommand
    {
    public:
        AddCommand(QGraphicsItem* graphicsItem, QGraphicsScene* scene, QUndoCommand *parent = nullptr);
        ~AddCommand();

        virtual void undo() override;
        virtual void redo() override;

    private:
        QGraphicsItem *m_GraphicsItem;
        QGraphicsScene *m_GraphicsScene;
        QPointF initialPosition;
    };

    // 删除元素时undo/redo
    class DeleteCommand : public QUndoCommand
    {
    public:
        explicit DeleteCommand(QGraphicsScene *graphicsScene, QUndoCommand *parent = nullptr);

        void undo() override;
        void redo() override;

    private:
        QGraphicsItem *m_GraphicsItem;
        QGraphicsScene *m_GraphicsScene;
    };

    // 鼠标移动元素时undo/redo
    class MoveCommand : public QUndoCommand
    {
    public:
        MoveCommand(QGraphicsItem* graphicsItem, const QPointF &oldPos, const QPoint &oldLastPos, std::function<void()> func_ptr_makePath = nullptr, std::function<void()> func_ptr_showChange = nullptr, QUndoCommand *parent = nullptr);
        void undo() override;
        void redo() override;
    private:
        QGraphicsItem *m_GraphicsItem;
        QPointF m_oldPos;
        QPointF newPos;
        QPoint m_oldLastPos;
        QPoint newLastPos;
        std::function<void()> m_func_ptr_makePath;
        std::function<void()> m_func_ptr_showChange;
    };

//    // keyPress移动元素时undo/redo
//    class KeyPressMoveCommand : public QUndoCommand
//    {
//    public:
//        KeyPressMoveCommand(QGraphicsItem* graphicsItem, const QPointF &oldPos, QUndoCommand *parent = nullptr);
//        void undo() override;
//        void redo() override;
//    private:
//        QGraphicsItem *m_GraphicsItem;
//        QPointF m_oldPos;
//        QPointF newPos;
//    };

    // 颜色变更时undo/redo
    class ChangeItemColorCommand : public QUndoCommand
    {
    public:
        ChangeItemColorCommand(QGraphicsItem* graphicsItem, QColor oldColor, YGraphicsTipItemPanel *yGraphicsTipItemPanel = nullptr, QUndoCommand *parent = nullptr);
        void undo() override;
        void redo() override;
    private:
        QGraphicsItem *m_GraphicsItem;
        YGraphicsTipItemPanel *m_YGraphicsTipItemPanel;
        QColor m_oldColor;
        QColor newColor;
    };

    // 文字颜色变更时undo/redo
    class ChangeTextItemColorCommand : public QUndoCommand
    {
    public:
        ChangeTextItemColorCommand(QGraphicsItem* graphicsItem, QColor oldColor, std::function<void()> func_ptr_setFontColor = nullptr, QUndoCommand *parent = nullptr);
        void undo() override;
        void redo() override;
    private:
        QGraphicsItem *m_GraphicsItem;
        QColor m_oldColor;
        QColor newColor;
        std::function<void()> m_func_ptr_setFontColor;
    };

    // 文字size变更时undo/redo
    class ChangeTextItemSizeCommand : public QUndoCommand
    {
    public:
        ChangeTextItemSizeCommand(QGraphicsItem* graphicsItem, int oldSize, std::function<void()> func_ptr_setFontSize = nullptr, QUndoCommand *parent = nullptr);
        void undo() override;
        void redo() override;
    private:
        QGraphicsItem *m_GraphicsItem;
        int m_oldSize;
        int newSize;
        std::function<void()> m_func_ptr_setFontSize;
    };

    // 文字weight变更时undo/redo
    class ChangeTextItemWeightCommand : public QUndoCommand
    {
    public:
        ChangeTextItemWeightCommand(QGraphicsItem* graphicsItem, int oldWeight, bool oldBold, std::function<void()> func_ptr_setFontWeight = nullptr, QUndoCommand *parent = nullptr);
        void undo() override;
        void redo() override;
    private:
        QGraphicsItem *m_GraphicsItem;
        int m_oldWeight;
        int newWeight;
        bool m_oldBold;
        int newBold;
        std::function<void()> m_func_ptr_setFontWeight;
    };

    // Rect大小变更时undo/redo
    class ChangeRectItemSizeCommand : public QUndoCommand
    {
    public:
        ChangeRectItemSizeCommand(QGraphicsItem* graphicsItem, const QPointF &oldPos, const QRectF &oldRect, const QSizeF &oldSize, std::function<void()> func_ptr_reChangePos = nullptr, QUndoCommand *parent = nullptr);
        void undo() override;
        void redo() override;
    private:
        QGraphicsItem *m_GraphicsItem;
        QPointF m_oldPos;
        QPointF newPos;
        QRectF m_oldRect;
        QRectF newRect;
        QSizeF m_oldSize;
        QSizeF newSize;
        std::function<void()> m_func_ptr_reChangePos;
    };

    // Ellipse大小变更时undo/redo
    class ChangeEllipseItemSizeCommand : public QUndoCommand
    {
    public:
        ChangeEllipseItemSizeCommand(QGraphicsItem* graphicsItem, const QPointF &oldPos, const QRectF &oldRect, const QSizeF &oldSize, std::function<void()> func_ptr_reChangePos = nullptr, QUndoCommand *parent = nullptr);
        void undo() override;
        void redo() override;
    private:
        QGraphicsItem *m_GraphicsItem;
        QPointF m_oldPos;
        QPointF newPos;
        QRectF m_oldRect;
        QRectF newRect;
        QSizeF m_oldSize;
        QSizeF newSize;
        std::function<void()> m_func_ptr_reChangePos;
    };

    // Arrow大小变更时undo/redo
    class ChangeArrowItemSizeCommand : public QUndoCommand
    {
    public:
        ChangeArrowItemSizeCommand(QGraphicsItem* graphicsItem, const QPointF &oldPos, const QPoint &oldLastPos, std::function<void()> func_ptr_makePath = nullptr, QUndoCommand *parent = nullptr);
        void undo() override;
        void redo() override;
    private:
        QGraphicsItem *m_GraphicsItem;
        QPointF m_oldPos;
        QPointF newPos;
        QPoint m_oldLastPos;
        QPoint newLastPos;
        std::function<void()> m_func_ptr_makePath;
    };

//    // 大小变更时undo/redo
//    class ChangeItemSizeCommand : public QUndoCommand
//    {
//    public:
//        ChangeItemSizeCommand(QGraphicsItem* graphicsItem, const QPointF &oldPos, const QPoint &oldLastPos, const QRect &oldRect, const QSizeF &oldSize, std::function<void()> fun_ptr_reChangePos = nullptr, QUndoCommand *parent = nullptr);
//        void undo() override;
//        void redo() override;
//    private:
//        QGraphicsItem *m_GraphicsItem;
//        QSizeF m_oldSize;
//        QSizeF newSize;
//        QPoint m_oldLastPos;
//        QPoint newLastPos;
//        QRectF m_oldRect;
//        QRectF newRect;
//        std::function<void()> m_func_ptr_reChangePos;
//    };

    // 粗细变更时undo/redo
    class ChangeItemThicknessCommand : public QUndoCommand
    {
    public:
        ChangeItemThicknessCommand(QGraphicsItem* graphicsItem, int oldThickness, std::function<void()> func_ptr_reChangePos = nullptr, std::function<void()> func_ptr_makePath = nullptr, QUndoCommand *parent = nullptr);
        void undo() override;
        void redo() override;
    private:
        QGraphicsItem *m_GraphicsItem;
        int m_oldThickness;
        int newThickness;
        std::function<void()> m_func_ptr_reChangePos;
        std::function<void()> m_func_ptr_makePath;
    };

    QString createCommandString(QGraphicsItem *item, const QPointF &point);
}
